package com.junjiao.util.web;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * URL工具类
 * 	检查URL：checkUrl
 *  读取指定URL地址内容：read
 *  POST提交URL：httpClientPost
 * 
 * @author jiaojun
 *         <p>
 *         email:junjiao.j@gmail.com
 *         </p>
 * @version v0.0.1
 * @date 2012-5-17
 */
public class URLUtil {

	private static final Log log = LogFactory.getLog(URLUtil.class);

	/**
	 * 检查url是否存在
	 * 
	 * @param postURL
	 * @return
	 */
	public static boolean checkUrl(String postURL) {
		try {
			URL url = new URL(postURL);
			HttpURLConnection urlcon = (HttpURLConnection) url.openConnection();
			urlcon.setRequestMethod("GET");
			urlcon.setRequestProperty("Content-type",
					"application/x-www-form-urlencoded");
			if (urlcon.getResponseCode() != HttpURLConnection.HTTP_OK) {
				return false;
			} else {
				return true;
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (ProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 读取指定url地址的内容，并转换为字符串
	 * 
	 * @param urlStr
	 * @return
	 */
	public static String read(String urlStr) {
		try {
			URL url = new URL(urlStr);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();
			connection.connect();
			InputStream in = connection.getInputStream();
			BufferedReader read = new BufferedReader(new InputStreamReader(in));
			StringBuffer buf = new StringBuffer();
			String line = null;
			while ((line = read.readLine()) != null) {
				buf.append(line);
			}
			return buf.toString();
		} catch (MalformedURLException e) {
			return null;
		} catch (IOException e) {
			return null;
		}
	}

	/**
	 * 读取指定图片的url地址，并转换为文件返回
	 * 
	 * @param imgUrl
	 * @return
	 */
	public static File readImg(String imgUrl) {
		BufferedImage img = loadImageUrl(imgUrl);
		String[] temp = imgUrl.split("/");
		String t = temp[temp.length - 1];
		writeImageLocal(t, img);

		return new File(t);
	}

	public static byte[] readBytes(String url) {
		byte[] responseBody = {};
		// 构造HttpClient的实例
		HttpClient httpClient = new HttpClient();
		// 创建GET方法的实例
		GetMethod getMethod = new GetMethod(url);
		// 使用系统提供的默认的恢复策略
		getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());
		try {
			// 执行getMethod
			int statusCode = httpClient.executeMethod(getMethod);
			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("Method failed: "
						+ getMethod.getStatusLine());
			}
			// 读取内容
			responseBody = getMethod.getResponseBody();
			// 处理内容
		} catch (HttpException e) {
			log.info("发生致命的异常，可能是协议不对或者返回的内容有问题！");
			log.info("responseCharset:" + getMethod.getResponseCharSet());
			log.info("responseBody" + responseBody);
			log.error("发生致命的异常，可能是协议不对或者返回的内容有问题！");
			log.error("responseCharset:" + getMethod.getResponseCharSet());
			log.error("responseBody" + responseBody);
		} catch (IOException e) {
			log.error("发生网络异常:"+e.getMessage());
		} finally {
			// log.info("responseCharset:"+getMethod.getResponseCharSet());
			// 释放连接
			getMethod.releaseConnection();
		}
		return responseBody;
	}

	public static String readStringByCharset(String url, String charset) {
		String str = "";
		try {
			str = new String(URLUtil.readBytes(url), charset);
		} catch (Exception e) {
			str = new String(URLUtil.readBytes(url));
		}
		return str;
	}

	/**
	 * HTTP post发送提交数据
	 * @param url
	 *            请求目标地址
	 * @param charset
	 *            字符编码
	 * @param parameters
	 *            为hashMap,要提交的参数
	 * @return byte[]
	 */
	public static byte[] httpClientPost(String url, String charset,
			HashMap<String, String> parameters) {
		byte[] responseBody = {};
		// 构造HttpClient的实例
		HttpClient httpClient = new HttpClient();
		// 创建POST方法的实例
		PostMethod postMethod = new PostMethod(url);
		postMethod.addRequestHeader("Content-Type",
				"application/x-www-form-urlencoded;charset=" + charset);
		// 使用系统提供的默认的恢复策略
		postMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());
		NameValuePair[] parametersBody = new NameValuePair[parameters.size()];
		try {
			Set<String> keySet = parameters.keySet();
			int i = 0;
			for (String key : keySet) {
				NameValuePair param = new NameValuePair(key, parameters
						.get(key));
				parametersBody[i++] = param;
			}
			postMethod.setRequestBody(parametersBody);
			// 执行getMethod
			int statusCode = httpClient.executeMethod(postMethod);
			if (statusCode != HttpStatus.SC_OK) {
				System.err.println("Method failed: "
						+ postMethod.getStatusLine());
			}
			// 读取内容
			responseBody = postMethod.getResponseBody();
			// 处理内容
		} catch (HttpException e) {
			log.error("发生致命的异常，可能是协议不对或者返回的内容有问题！");
			log.error("responseCharset:" + postMethod.getResponseCharSet());
			log.error("responseBody" + responseBody);
		} catch (IOException e) {
			log.error("发生网络异常:"+e.getMessage());
		} finally {
			// log.info("responseCharset:"+getMethod.getResponseCharSet());
			// 释放连接
			postMethod.releaseConnection();
		}
		return responseBody;
	}

	/**
	 * 编码
	 * @param s
	 * @return
	 */
	public static final String encodeRequestParameter(String s) {
		if (URLUtil.isContainChinese(s) == false) {
			return s;
		}
		try {
			return URLEncoder.encode(s, "utf-8").replaceAll("%", ":");
		} catch (Exception e) {
			return "";
		}

	}

	/**
	 * 解码
	 * @param s
	 * @return
	 */
	public static final String decodeRequestParameter(String s) {
		try {
			return URLDecoder.decode(s.replaceAll(":", "%"), "utf-8");
		} catch (Exception e) {
			log.error(e.getMessage());
		}
		return "";
	}

	/**
	 * 判断url中是否包含中文
	 * @param s
	 * @return
	 */
	private static boolean isContainChinese(String s) {
		if (s == null || s.trim().equals("")) {
			return false;
		}
		for (int i = 0; i < s.length(); i++) {
			if (s.substring(i, i + 1).matches("[\u4e00-\u9fa5]+")) {
				return true;
			}
		}
		return false;

	}

	/**
	 * 导入网络图片到缓冲区
	 */
	public static BufferedImage loadImageUrl(String imgName) {
		try {
			URL url = new URL(imgName);
			return ImageIO.read(url);
		} catch (IOException e) {
			log.error(e.getMessage());
		}
		return null;
	}

	/**
	 * 生成新图片到本地
	 */
	public static void writeImageLocal(String newImage, BufferedImage img) {
		if (newImage != null && img != null) {
			try {
				File outputfile = new File(newImage);
				ImageIO.write(img, "gif", outputfile);
			} catch (IOException e) {
				log.error(e.getMessage());
			}
		}
	}

	/**
	 * 获取客户端ip
	 * @param request
	 * @return
	 */
	public static String getRemortIP(HttpServletRequest request) {
		if (request.getHeader("x-forwarded-for") == null) {
			return request.getRemoteAddr();
		}
		return request.getHeader("x-forwarded-for");
	}
	
}
